import {
	split_index,
	count_front
} from '@/config/ssq-config';
import FsDriver from './FsDriver';

const fsDriver = new FsDriver();

/**
 * 数据源模型类
 * @version 1.0.1
 */
class SsqDataModel {

	/**
	 * 缓存键名
	 */
	cacheKeyOfDataSource = 'ssq-data-source';
	cacheKeyOfRefreshTime = 'ssq-refresh-time';
	cacheKeyOfActiveDrawNum = 'ssq-active-draw-num';


	/**
	 * 设置数据源
	 * @param {Array} rows 
	 */
	setDataSource(list) {
		// 增量添加
		let data = JSON.parse(fsDriver.get(this.cacheKeyOfDataSource) ?? '[]');
		if (data.length > 0 && (list[list.length - 1].lotteryDrawNum < data[0].lotteryDrawNum)) {
			data.unshift(...list.filter(row => row.lotteryDrawNum > data[0].lotteryDrawNum));
			if (data.length > 100) {
				data = data.slice(0, 100);
			}
		} else {
			data = list;
		}
		fsDriver.save(this.cacheKeyOfDataSource, JSON.stringify(data));
		console.log('【SsqDataSource数据库】setDataSource ', data);
	}

	/**
	 * 返回数据源
	 * @returns {Array} 示例：[{lotteryDrawNum: "25066", lotteryDrawResult: "15 18 27 28 34 03 06", lotteryDrawTime: "2025-06-14"}, ...]
	 */
	getDataSource(activeDrawNum = '') {
		let dataset = JSON.parse(fsDriver.get(this.cacheKeyOfDataSource) ?? '[]');
		if (activeDrawNum !== '') {
			let pos = dataset.findIndex(v => v.lotteryDrawNum == activeDrawNum);
			if (pos > -1) {
				return dataset.slice(pos);
			}
		}
		return dataset;
	}

	getLastRecord() {
		let dataset = this.getDataSource();
		return dataset.length > 0 ? dataset[dataset.length - 1] : {};
	}

	/**
	 * 设置时光机期号
	 * @param {Number} num 
	 */
	setActiveDrawNum(num) {
		fsDriver.save(this.cacheKeyOfActiveDrawNum, num);
	}

	/**
	 * 获取时光机期号
	 * @returns {String} 返回期号
	 */
	getActiveDrawNum() {
		return fsDriver.get(this.cacheKeyOfActiveDrawNum) || '';
	}

	/**
	 * 设置刷新时间
	 */
	setRefreshTime() {
		let refreshTime = new Date().getTime();
		fsDriver.save(this.cacheKeyOfRefreshTime, refreshTime);
	}

	getRefreshTime(isLocalString = false) {
		let refreshTime = parseInt(fsDriver.get(this.cacheKeyOfRefreshTime) ?? '0');
		if (isLocalString && refreshTime > 0) {
			// 返回本地存储的时间字符串
			return new Date(parseInt(refreshTime)).toLocaleString('zh-CN', {
					year: 'numeric',
					month: '2-digit',
					day: '2-digit',
					hour: '2-digit',
					minute: '2-digit',
					second: '2-digit',
					weekday: "short",
				})
				.replaceAll('/', '-').replace('周', ' 周');
		}
		return refreshTime;
	}

	/**
	 * 检测刷新时间是否过期
	 * @param {Number} time 秒
	 * @returns Boolean 如果超过指定时间，则返回 true，表示需要刷新数据
	 */
	isExpire(time = 7200) {
		return (new Date().getTime() - this.getRefreshTime(false)) > (time * 1000);
	}

	/**
	 * 返回指定号数的列数据
	 * @param {Array} data 数据
	 * @param {Number} columnIdx 号数列索引（从 0 到 6）
	 * @param {Boolean} isLocation 是否是位置数据
	 * @returns {Array}
	 */
	getColumnData(data, columnIdx, isLocation = false) {
		// const data = getDataSource();
		if (isLocation) {
			let inc = columnIdx < split_index ? 0 : count_front;
			// 返回位置数据，前 5 列是红球，后 2 列是蓝球
			return data.map((row, i) => {
				return [i, parseInt(row.lotteryDrawResult.split(' ')[columnIdx]) + inc];
			});
		}
		return data.map(row => row.lotteryDrawResult.split(' ')[columnIdx]);
	}

	/**
	 * 获取每个号码的出现次数统计。包含全部号码（前后区）统计和每个号数列（1-7）的统计
	 * @param {Array} data 数据源，默认为当前数据源
	 * @returns Object {statAll, statColumns}
	 */
	getDrawalStat(data) {
		if (!data) {
			data = this.getDataSource();
		}
		let statColumns = [{}, {}, {}, {}, {}, {}, {}]; // 1...7
		let statAll = [{}, {}]; // front/back
		let pos = 0; // 是否是前区号码
		data.forEach(row => {
			row.lotteryDrawResult.split(' ').forEach((num, i) => {
				pos = i < split_index ? 0 : 1;
				statAll[pos][num] = statAll[pos][num] ? statAll[pos][num] + 1 : 1;
				statColumns[i][num] = statColumns[i][num] ? statColumns[i][num] + 1 : 1;
			});
		});
		// 排序
		let statAllSorted = [{}, {}];
		for (let i = 0; i < 2; i++) {
			Object.keys(statAll[i]).sort().forEach(key => {
				statAllSorted[i]['N' + key] = statAll[i][key];
			});
		}
		statAll = null;
		let statColumnsSorted = [],
			statSorted = {};
		statColumns.forEach((statObj, i) => {
			statSorted = {};
			Object.keys(statObj).sort().forEach(key => {
				statSorted['N' + key] = statObj[key];
			});
			statColumnsSorted[i] = statSorted;
		});
		statColumns = null;
		return {
			statAll: statAllSorted,
			statColumns: statColumnsSorted
		};
	}

	/**
	 * 获取大乐透官方远程数据
	 * @returns Array 
	 * 数据结构
	 * list = [ drawing1, drawing2, ...]
	 * drawing = {lotteryDrawNum: "24023", lotteryDrawResult: "08 10 12 14 22 05 09",lotteryUnsortDrawresult: "12 14 08 10 22 05 09"}
	 */
	fetchData() {
		return new Promise((resolve, reject) => {
			const url =
				'https://webapi.sporttery.cn/gateway/lottery/getHistoryPageListV1.qry?gameNo=85&provinceId=0&pageSize=60&isVerify=1&pageNo=1&termLimits=60';
			uni.request({
				url,
				success: (res) => {
					console.log('【获取大乐透官方远程数据】成功', res);
					resolve((res['data'] ? res.data : res).value.list.map(row => {
						const {
							lotteryDrawNum,
							lotteryDrawResult,
							lotteryDrawTime
						} = row;
						return {
							lotteryDrawNum,
							lotteryDrawResult,
							lotteryDrawTime
						};
					}));
				},
				fail: (err) => {
					console.log('【获取大乐透官方远程数据】网络错误', err);
					reject(err);
				}
			})
		})
	}

	/**
	 * 封装加载数据方法
	 * @param {Boolean} isForce 是否强制刷新数据。默认 false。
	 * @returns 
	 */
	loadData(isForce = false) {
		return new Promise((resolve, reject) => {
			if (isForce || this.isExpire() || this.getDataSource().length === 0) {
				console.log('重新加载大乐透数据。刷新时间:', this.getRefreshTime(true));
				this.fetchData().then(rows => {
					console.log('加载大乐透数据成功');
					this.setRefreshTime();
					this.setDataSource(rows);
					resolve(rows);
				}).catch(err => {
					console.log('加载大乐透数据错误', err);
					reject(err);
				});
			} else {
				console.log('使用大乐透缓存数据。刷新时间:', this.getRefreshTime(true));
			}
		});
	}
}

export default SsqDataModel;